package edu.hawaii.duedates;

import com.meterware.httpunit.GetMethodWebRequest;
import com.meterware.httpunit.HttpUnitOptions;
import com.meterware.httpunit.WebConversation;
import com.meterware.httpunit.WebForm;
import com.meterware.httpunit.WebRequest;
import com.meterware.httpunit.WebResponse;
import com.meterware.httpunit.WebTable;

/**
 * DueDates demonstrates simple use of httpunit to retrieve and parse a web page.
 * DueDates when invoked through the command line will retrieve information from the library.
 * 
 * 
 * @author Philip Johnson Team Purple John Ancheta Daniel Arakaki Marilee Flestado
 * 
 * @version 1.1, October 14, 2008
 */
public class DueDates {

  /**
   * Attempts to login to UH Manoa Library system.
   * 
   * @param id The UH user ID.
   * @param lastName The UH user's last name.
   * @return The WebConversation instance after successful login.
   * @throws Exception If login was not successful with these credentials.
   */
  private static WebConversation loginToUhmLibrary(final String id, final String lastName)
      throws Exception {
    String url = "http://uhmanoa.lib.hawaii.edu/cgi-bin/Pwebrecon.cgi?DB=local&PAGE=pbLogon";
    // UH Library website has bogus JavaScript code.
    HttpUnitOptions.setExceptionsThrownOnScriptError(false);
    // create the conversation object which will maintain state for us
    WebConversation conversation = new WebConversation();
    WebRequest request = new GetMethodWebRequest(url);
    WebResponse response = conversation.getResponse(request);
    WebForm form = response.getFormWithName("logonpage");
    if (id.length() == 9 && id.charAt(4) == '-') {
      form.setParameter("BC", id.substring(0, 4) + id.substring(5));
    }
    else {
      form.setParameter("BC", id);
    }
    form.setParameter("LN", lastName);
    form.submit();
    response = conversation.getCurrentPage();
    if (response.getText().contains("Sorry, Login unsuccessful")) {
      throw new Exception("Error while logging in to UH Library");
    }
    return conversation;
  }
  
  /**
   * Given a logged in user to the UH Library site, provides info about their library books.
   * Should a user have books checked out a formatted list will be presented.
   * If no books are borrowed then a message will be displayed.
   * 
   * @param id The UH user ID.
   * @param lastName The UH user's last name.
   * @return A String containing information about their books.
   * @throws Exception If problems occur parsing the site pages.
   */
  public String getUhmInfo(String id, String lastName) throws Exception {
    try {
      WebConversation conversation = loginToUhmLibrary(id, lastName);
      WebResponse response = conversation.getCurrentPage();
      WebForm form = response.getForms()[0];
      String uhSiteNoItemString = "You have no items checked out.";
      if (uhSiteNoItemString.equals(form.getText())) {
        return "No books checked out";
      }
      else {
        StringBuffer bookInfo = new StringBuffer();
        bookInfo.append("Due date\tBook Info\n");
        WebTable table = response.getTables()[0];
        for (int i = 1; i <= table.getRowCount() - 1; i++) {
          String recordDueDate = table.getCellAsText(i, 3); 
          if (recordDueDate.length() >= 8) {
            recordDueDate = recordDueDate.substring(recordDueDate.length() - 8);
          }
          String recordBookInfo =  table.getCellAsText(i, 1); 
          bookInfo.append(recordDueDate + "\t" + recordBookInfo  + "\n");
        }
        return bookInfo.toString();
      }
    }
    catch (Exception e) {
      throw new Exception("Unable to get UH Book info:\n  " + e.getMessage(), e);
    }
  }

  /**
   * The getSiteInfo method gets the information from the command line.
   * The method needs an argument to verify which site it taking information from. 
   * 
   * @param optionSite A String taken in from the command line which signifies the library's code.
   * @param id A String of the user's library id number.
   * @param lastName A String of the user's last name.
   * @return A String of the user's information from the getUhmInfo method.
   * @throws Exception An exception is thrown when an error occurs while retrieving library
   *         information.
   */
  public static String getSiteInfo(String optionSite,
                                   String id,
                                   String lastName) throws Exception {
    DueDates dueDates = new DueDates();
    if (dueDates.isUhmOption(optionSite)) {
      return dueDates.getUhmInfo(id, lastName);
    }
    else {
      throw new Exception("Error unknown site option \"" + optionSite + "\".");
    }
  }
  
  /**
   *  This method assures the proper site is chosen from the command line.
   *  
   *  @param option This is an option.
   *  @return true if the option equals "-uhm".
   */
  public boolean isUhmOption(String option) {
    return "-uhm".equals(option);
  }

  /**
   * The main method handles the command line arguments and prints a stack trace when invoked.
   * 
   * @param params Four strings: uhID, uhLastName, hiStateId, hiStatePassword.
   */
  public static void main(String[] params) {
    boolean verbose = false;
    String siteInfo = "\n";
    try {
      if (params.length == 4) {
        verbose = "-verbose".equals(params[0]);
        siteInfo = DueDates.getSiteInfo(params[1], params[2], params[3]);
      }
      else if (params.length == 3) { 
        siteInfo = DueDates.getSiteInfo(params[0], params[1], params[2]);
      }
      else {
        System.out.println("DueDates Usage: java -jar [-verbose] -uhm <id> <last name>");
      }
    }
    catch (Exception e) {
      if (verbose) {
        e.printStackTrace();
      }
      else {
        System.out.println(e.getMessage());
      } 
    } 
    System.out.println(siteInfo);
  }
}
